/*******************************************************************************

ATTENTION, this is an altered version of the xhtml_gen library, specifically tailored to libwebconf's needs please refer to the original library

xhtml_gen: xhtml generation library.
Copyright (c) 2006  Mitchel Haas

This software is provided 'as-is', without any express or implied warranty. 
In no event will the author be held liable for any damages arising from 
the use of this software.

Permission is granted to anyone to use this software for any purpose, 
including commercial applications, and to alter it and redistribute it freely, 
subject to the following restrictions:

1.	The origin of this software must not be misrepresented; 
you must not claim that you wrote the original software. 
If you use this software in a product, an acknowledgment in the product 
documentation would be appreciated but is not required.

2.	Altered source versions must be plainly marked as such, 
and must not be misrepresented as being the original software.

3.	The above copyright notice and this permission notice may not be removed 
or altered from any source distribution.

For complete documentation on this library, see http://www.datasoftsolutions.net
Email questions, comments or suggestions to mhaas@datasoftsolutions.net
*******************************************************************************/

#include "xhtml_doc.hpp"

namespace xhtml_gen
{


std::string xhtml_doc::get_doctype() const
{
	return "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
}


xhtml_doc::xhtml_doc() : pHtml_element(0)
{
	pHtml_element = new xhtml_element(html);
	*pHtml_element << xhtml_element(xhtml_gen::head);
	*pHtml_element << xhtml_element(xhtml_gen::body);
}

xhtml_doc::xhtml_doc(const xhtml_doc& _src) : pHtml_element(new xhtml_element(*_src.pHtml_element))
{
}

xhtml_doc& xhtml_doc::operator =(const xhtml_doc& _rhs)
{
	if ( &_rhs == this) 
		return *this;
	
	delete pHtml_element;
	pHtml_element = new xhtml_element(*_rhs.pHtml_element);

	return *this;
}

xhtml_doc::~xhtml_doc()
{
	delete pHtml_element;
}

xhtml_doc& xhtml_doc::operator << (const xhtml_element& _elem)
{
	insert(_elem);
	return *this;
}

xhtml_doc& xhtml_doc::operator << (const std::string& _pcData)
{
	insert(_pcData);
	return *this;
}

xhtml_element::iterator xhtml_doc::insert(const std::string& _pcData)
{
	return ((*pHtml_element)[1]).insert(_pcData);
}

xhtml_element::iterator xhtml_doc::insert(const xhtml_element& _elem)
{
	const tag* const pElemTag = _elem.get()->get_tag();

	if (pElemTag) {
		// tag
		if (pElemTag->get_tag_enumeration() == html) {
			// html xhtml_element passed
			*pHtml_element = _elem;
			xhtml_element::iterator it = pHtml_element->begin();
			++it;
			return it;
		} else if ( pElemTag->get_tag_enumeration() == xhtml_gen::head ) {
			// head or body xhtml_element passed
			(*pHtml_element)[0].set(_elem);
			return pHtml_element->begin();
		} else if (pElemTag->get_tag_enumeration() == xhtml_gen::body ) {
			(*pHtml_element)[1].set(_elem);
			xhtml_element::iterator it = pHtml_element->begin();
			++it;
			return it;
		} else {
			// see if cdata or xhtml_element which can be in body
			tag tag_(xhtml_gen::body);
			if (tag_.validate_nesting(pElemTag)) {
				// insert elem into body
				return ((*pHtml_element)[1]).insert(_elem);
			}	
		}
	} else {
		// pcdata.  insert into body
		return ((*pHtml_element)[1]).insert(_elem);
	}

	return pHtml_element->end();
}

std::string xhtml_doc::get_xhtml() const
{
	std::ostringstream ostr;
	ostr << get_doctype();

	ostr << pHtml_element->get_xhtml();

	return ostr.str();

}

bool xhtml_doc::save( const std::string& _path ) const
{
	std::ofstream file( _path.c_str() );
 	if ( file ) {
		file << get_doctype();
		
		file << pHtml_element->get_xhtml();

		file.close();
		return true;
	}
	return false;

}

void xhtml_doc::add_stylesheet_link(const std::string& _path)
{
	std::ostringstream opath;
	opath << _path;

	xhtml_element link_elem(link);
	link_elem.set_attribute(rel, "stylesheet");
	link_elem.set_attribute(type, "text/css");
	link_elem.set_attribute(href, opath.str());

	(*pHtml_element)[0] << link_elem;
}

void xhtml_doc::add_stylesheet(const stylesheet& _ss)
{
	xhtml_element style_elem(style);
	style_elem.set_attribute(type, "text/css");
	style_elem << _ss.get_css(1);
	(*pHtml_element)[0] << style_elem;
}


xhtml_element* xhtml_doc::head() 
{ 
	return *pHtml_element->children.begin();
}

xhtml_element* xhtml_doc::body() 
{ 
	std::vector<xhtml_element*>::iterator it = pHtml_element->children.begin();
	++it;
	return *it;
}


}

